import json
from datetime import datetime
from urllib import parse

from django.db import transaction
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.urls import reverse
from django.views import View
from rest_framework import status, generics, exceptions, viewsets, mixins, request
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from apps.oaauth.models import OADepartment, OAUser
from apps.oaauth.serializers import DepartmentSerializer, UserSerializer
from oabanck import settings
from .paginations import StaffListPagination
from .serializers import staffSerializer,ActiveStaffSerializer
from utils  import aeser
from oabanck.celery import debug_task
from .tasks import send_mail_task
from  apps.oaauth.models import UserStatusChoices
import pandas as pd
from .serializers import StaffUploadSeriazlizer

aes = aeser.AESCipher(settings.SECRET_KEY)


# Create your views here.
class ActiveStaffView(View):
    def get(self, request):
        ## 获取 token 并把 token 存储到 cookie 中 方便下次用户传过来
        token = request.GET.get("token")
        print(f"邮件激活的token是 : {token}")
        response = render(request,"active.html")
        print(f"未添加cookie 之前的 response 中的 cookie 是 {dict(response.cookies)}")
        response.set_cookie('token', token)
        print(f"添加cookie 之后的 response 中的 cookie 是 {dict(response.cookies)}")

        return response

    def post(self, request):
        ## 从 cookie中 获取 token
        try:
            print("-------------post 激活方法")
            token = request.COOKIES.get("token")  ## 从 cookies中获取
            print(f"token is {token}")
            email = aes.decrypt(token)
            print(f"解密出来的 email is {email}")
            serializer = ActiveStaffSerializer(data=request.POST)
            if serializer.is_valid():
                ## 从序列化中获取到数据
                form_email = serializer.validated_data.get('email')
                print(f"----------form_email is {form_email}")
                print(f"----------serializer.validated_data.get('email') is {serializer.validated_data.get('email')}")
                user = serializer.validated_data.get('user')
                print(f"views 中的 user is {user}")
                if email != form_email:
                    return JsonResponse({"code":400,"message":"邮箱密码错误"})
                ## 修改激活状态
                user.status = UserStatusChoices.ACTIVED
                user.save()
                return JsonResponse({"code":200,"message":""})
            else:
                detail = list(serializer.errors.values())[0][0]
                return JsonResponse({"code":400,"message":detail})
        except Exception as e:
            return JsonResponse({"code":400,"message":str(e)})


class DepartmentListView(ListAPIView):
    queryset =  OADepartment.objects.all()
    serializer_class = DepartmentSerializer

    def get(self, request, *args, **kwargs):
        print("DepartmentListView 被请求了")
        return super().get(request, *args, **kwargs)


class StaffViewSet(
    viewsets.GenericViewSet,
    mixins.ListModelMixin,
    mixins.CreateModelMixin,
    mixins.UpdateModelMixin
):
    queryset = OAUser.objects.all()
    pagination_class = StaffListPagination

    ## 定于视图集使用的 序列化

    def get_serializer_class(self):
        if self.request.method in ["GET","PUT"]:
            return UserSerializer
        else:
            return staffSerializer

    ## 获取员工列表
    def get_queryset(self):
        print(f"request.query_params is {self.request.query_params}")
        queryset = self.queryset
        ##
        department_id = self.request.query_params.get('department_id')
        realname = self.request.query_params.get('realname')
        date_joined = self.request.query_params.getlist('date_joined[]')


        ##
        user = self.request.user
        if user.department.name != '董事会':
            if user.uid != user.department.leader.uid:
                return exceptions.PermissionDenied()
            else:
                queryset = queryset.filter(department_id=user.department.id)
        else:
            # 董事会中 根据部门ID 进行 过滤
            if department_id:
                queryset = queryset.filter(department_id=department_id)
            ## 按 姓名查找
        if realname:
            queryset = queryset.filter(realname__icontains=realname)
        if date_joined:
            try:
                start_date = datetime.strptime(date_joined[0],"%Y-%m-%d")
                '''
                    2025-09-05 在经过 datetime.strptime(date_joined[1], "%Y-%m-%d") 转换后 会变成 2025-09-05 00:00:00
                    .replace(hour=23, minute=59, second=59)  是将当天的时间变成  2025-09-05 23:59:59
                    '''
                end_date = datetime.strptime(date_joined[1],"%Y-%m-%d").replace(hour=23,minute=59,second=59)

                queryset = queryset.filter(date_joined__range=(start_date,end_date))
            except:
                pass
        return queryset.order_by('-date_joined').all()


    def update(self, request, *args, **kwargs):
        ## 允许只更新部分字段的值
        kwargs['partial'] = True
        return super().update(request, *args, **kwargs)



    def create(self,request,*args,**kwargs):
        print(f"request is {request}")
        print(f"request.data is {request.data}")
        serializer = staffSerializer(data=request.data,context={'request':request})
        print(f"serializer.is_valid() is {serializer.is_valid()}")
        if serializer.is_valid():
            ## 获取数据
            realname = serializer.validated_data.get('realname')
            email = serializer.validated_data.get('email')
            password = serializer.validated_data.get('password')

            user = OAUser.objects.create_user(realname=realname, email=email, password=password)
            ## 给新增加的员工设置部门
            department = request.data.get('department')
            user.department = department
            user.save()
            ## 发送邮件
            send_active_mail(email)
            return Response(status=status.HTTP_201_CREATED)

        else:
            return Response(data={'detail': list(serializer.errors.values())[0][0]}, status=status.HTTP_400_BAD_REQUEST)

'''
   ##发送邮件激活
  send_mail(
      subject=f"【知了OA】账户激活",
      message='这是一封激活邮件，请点击链接完成注册：http://zhiliao-oa.com/activate/xxx',
      from_email=settings.EMAIL_HOST_USER,
      recipient_list=[email],
      fail_silently=False,  # 推荐开发时设为 False，便于发现问题
      )
  '''
def send_active_mail(request,email):
    token = aes.encrypt(email)
    active_path = reverse("staff:activeview") + "?" + parse.urlencode({"token": token})
    print(f"============active_path: {active_path}""")
    active_url = request.build_absolute_uri(active_path)
    print(f"===========active_url: {active_url}")
    message=f"请点击下面链接,用来激活账户,{active_url}"
    email_list = ['3622739389@qq.com', '13367812895@163.com']
    subject = f"【知了OA】账户激活"
    ## 使用 celery 异步发送
    send_mail_task.delay(email_list,subject,message)


class TestCeleryview(APIView):
    def get(self, request):
        ## 这个只回在 Django 中输出
        print("-------我是views 中的方法 开始调度 celery ")
        debug_task.delay()
        return Response({"detail":"测试成功"},status=status.HTTP_200_OK)


## 下载功能
class StaffDownloadView(APIView):
    def get(self, request):
        ## /staff/download?pks[x,y]  ['x','y'] -> json格式的字符串
        pks_param = request.query_params.get("pks")
        print(f"pks_param: {pks_param}")
        try:
            pks = json.loads(pks_param)
            print(f"pks is {pks}")
        except Exception as e:
            return Response({"detail":"员工参数错误！"},status=status.HTTP_400_BAD_REQUEST)
        try:
            current_user = request.user
            queryset = OAUser.objects
            if current_user.department.name != '董事会':
                if current_user.department.leader_id != current_user.uid:
                    return Response({"detail":"没有权限下载!"},status=status.HTTP_400_BAD_REQUEST)
                else:
                    queryset = queryset.filter(department_id=current_user.department_id)
            queryset = queryset.filter(pk__in=pks)
            result = queryset.values("realname","email","department__name","date_joined","status").order_by("-date_joined")
            staff_df = pd.DataFrame(list(result))  ## DataFrame 类似 Excel 表格 都是一列一列的
            staff_df=staff_df.rename(columns={"realname":"姓名","email":'邮箱',"department__name":'部门',"date_joined":"入职时间","status":"状态"})

            ## 将入职时间进行格式化
            staff_df["入职时间"] = pd.to_datetime(staff_df["入职时间"]).dt.strftime("%Y-%m-%d %H:%M:%S")
            ## 将 staff_df 写道 response 当中
            response = HttpResponse(content_type='application/xlsx')
            response['Content-Disposition'] = 'attachment;filename="员工信息.xlsx"'

            ## 优化时间
            #staff_df["入职时间"] = pd.to_datetime(staff_df["date_joined"])
            ## 把 staff_df 写入到 Response 中
            with pd.ExcelWriter(response) as writer:
                staff_df.to_excel(writer,sheet_name="员工信息.xlsx",index=False)
            return response
        except Exception as e:
            print(f" exception occurred: {e}")
            return Response({"detail":str(e)},status=status.HTTP_400_BAD_REQUEST)

### 上传 excel 并完成入库 发送激活邮件通知
class StaffUploadView(APIView):
    def post(self,request):
        serializer = StaffUploadSeriazlizer(data=request.data)
        if serializer.is_valid():
            file = serializer.validated_data.get('file')
            current_user = request.user
            if current_user.department.name != '董事会' or current_user.department.leader_id != current_user.uid:
                return Response({'detail':'您无权限上传文件'},status=status.HTTP_403_FORBIDDEN)
            staff_df = pd.read_excel(file)  ## pands 读取 excel
            users = []
            ### 循环处理
            for index,row in staff_df.iterrows():
                ## 获取部分
                if current_user.department.name != "董事会":
                    department = current_user.department
                else:
                    try:
                        department = OADepartment.objects.filter(name=row['部门']).first()
                        if not department:
                            return Response({'detail':f'{row['部门']}不存在！'},status=status.HTTP_400_BAD_REQUEST)
                    except:
                        return Response({'detail':'部门列不存在！'},status=status.HTTP_400_BAD_REQUEST)

                    ### 从excel中读取数据
                try:
                    email = row['邮箱']
                    realname = row['姓名']
                    password = "admin"
                    user = OAUser(email=email,realname=realname,department=department,status=UserStatusChoices.UNACTIVED)
                    user.set_password(password)
                    users.append(user)  ### 后续批量导入
                except Exception as e:
                    return Response({'detail':"请检查文件中的邮箱、姓名、部门名称!"},status=status.HTTP_400_BAD_REQUEST)
                ### 批量导入为原子操作
            try:
                with transaction.atomic():
                    OAUser.objects.bulk_create(users)
            except Exception as e:
                return Response({"detail":"员工数据添加错误!"},status=status.HTTP_400_BAD_REQUEST)

            ### 异步发送激活邮件
            for user in users:
                send_active_mail(request,user.email)
            return Response()          
        else:
            detail = list(serializer.errors.values())[0][0]
            return Response({"detail":detail},status=status.HTTP_400_BAD_REQUEST)





